package response

import (
	"net/http"
	"time"

	"baseService/internal/pkg/errors"

	"github.com/gin-gonic/gin"
)

const (
	// ResponderKey 响应器在Context中的键名
	ResponderKey = "responder"
	// RequestIDKey 请求ID在Context中的键名
	RequestIDKey = "request_id"
	// StartTimeKey 请求开始时间键名
	StartTimeKey = "start_time"
)

// ResponderMiddleware 响应器中间件
func ResponderMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 记录请求开始时间
		startTime := time.Now()
		c.Set(StartTimeKey, startTime)

		// 获取或生成请求ID
		// 优先级：1.从Header获取 2.从Query获取 3.生成新的
		requestID := getOrGenerateRequestID(c)
		c.Set(RequestIDKey, requestID)

		// 设置响应头
		c.Header("X-Request-ID", requestID)
		c.Header("X-Response-Time", "")

		// 继续处理请求
		c.Next()

		// 计算响应时间并设置到响应头
		duration := time.Since(startTime)
		c.Header("X-Response-Time", duration.String())
	}
}

// GetResponder 从Context获取响应器
func GetResponder(c *gin.Context) Responder {
	if responder, exists := c.Get(ResponderKey); exists {
		if resp, ok := responder.(Responder); ok {
			return resp
		}
	}

	// 如果没有找到，创建一个新的（fallback）
	return NewResponder(c)
}

// getOrGenerateRequestID 获取或生成请求ID
func getOrGenerateRequestID(c *gin.Context) string {
	// 第一优先级：从Header获取（支持分布式追踪）
	if requestID := c.GetHeader("X-Request-ID"); requestID != "" {
		return requestID
	}

	// 第二优先级：从Query获取（方便调试）
	if requestID := c.Query("request_id"); requestID != "" {
		return requestID
	}

	// 最后：生成新的
	return generateRequestID()
}

// 便利函数，让Handler可以直接调用

// Success 成功响应便利函数
func Success(c *gin.Context, data interface{}, message ...string) {
	GetResponder(c).Success(data, message...)
}

// SuccessWithMsg 使用错误常量的成功响应
func SuccessWithMsg(c *gin.Context, data interface{}, msg string) {
	GetResponder(c).Success(data, msg)
}

// Pagination 分页响应便利函数
func Pagination(c *gin.Context, data interface{}, meta PaginationMeta, message ...string) {
	GetResponder(c).Pagination(data, meta, message...)
}

// List 列表响应便利函数
func List(c *gin.Context, data interface{}, message ...string) {
	GetResponder(c).List(data, message...)
}

// Error 错误响应便利函数
func Error(c *gin.Context, err error) {
	GetResponder(c).Error(err)
}

// BusinessError 业务错误便利函数
func BusinessError(c *gin.Context, message string, code ...ResponseCode) {
	GetResponder(c).BusinessError(message, code...)
}

// ValidationError 验证错误便利函数
func ValidationError(c *gin.Context, message string, details ...interface{}) {
	GetResponder(c).ValidationError(message, details...)
}

// NotFound 未找到便利函数
func NotFound(c *gin.Context, message ...string) {
	GetResponder(c).NotFound(message...)
}

// Unauthorized 未授权便利函数
func Unauthorized(c *gin.Context, message ...string) {
	GetResponder(c).Unauthorized(message...)
}

// Forbidden 禁止访问便利函数
func Forbidden(c *gin.Context, message ...string) {
	GetResponder(c).Forbidden(message...)
}

// InternalError 内部错误便利函数
func InternalError(c *gin.Context, message ...string) {
	GetResponder(c).InternalError(message...)
}

// === 使用错误常量的便利函数 ===

// ErrorWithConstant 使用错误常量的错误响应
func ErrorWithConstant(c *gin.Context, errMsg errors.ErrorMessage, code ...ResponseCode) {
	respCode := CodeInternalError
	if len(code) > 0 {
		respCode = code[0]
	}
	GetResponder(c).BusinessError(string(errMsg), respCode)
}

// ValidationErrorWithConstant 使用错误常量的验证错误
func ValidationErrorWithConstant(c *gin.Context, errMsg errors.ErrorMessage, details ...interface{}) {
	GetResponder(c).ValidationError(string(errMsg), details...)
}

// UnauthorizedWithConstant 使用错误常量的未授权错误
func UnauthorizedWithConstant(c *gin.Context, errMsg errors.ErrorMessage) {
	GetResponder(c).Unauthorized(string(errMsg))
}

// ForbiddenWithConstant 使用错误常量的禁止访问错误
func ForbiddenWithConstant(c *gin.Context, errMsg errors.ErrorMessage) {
	GetResponder(c).Forbidden(string(errMsg))
}

// NotFoundWithConstant 使用错误常量的未找到错误
func NotFoundWithConstant(c *gin.Context, errMsg errors.ErrorMessage) {
	GetResponder(c).NotFound(string(errMsg))
}

// 常用错误快捷函数

// InvalidRequest 无效请求错误
func InvalidRequest(c *gin.Context) {
	ErrorWithConstant(c, errors.ErrInvalidRequest, CodeBadRequest)
}

// InvalidJSON JSON格式错误
func InvalidJSON(c *gin.Context) {
	ErrorWithConstant(c, errors.ErrInvalidJSON, CodeBadRequest)
}

// ValidationFailed 验证失败错误
func ValidationFailed(c *gin.Context, details ...interface{}) {
	ValidationErrorWithConstant(c, errors.ErrValidationFailed, details...)
}

// Unauthorized 未授权错误
func UnauthorizedAccess(c *gin.Context) {
	UnauthorizedWithConstant(c, errors.ErrUnauthorized)
}

// TokenExpired 令牌过期错误
func TokenExpired(c *gin.Context) {
	ErrorWithConstant(c, errors.ErrTokenExpired, CodeTokenExpired)
	//UnauthorizedWithConstant(c, errors.ErrTokenExpired)
}

// InvalidCredentials 无效凭据错误
func InvalidCredentials(c *gin.Context) {
	ErrorWithConstant(c, errors.ErrTokenExpired, CodeTokenInvalid)

	//UnauthorizedWithConstant(c, errors.ErrInvalidCredentials)
}

// PermissionDenied 权限不足错误
func PermissionDenied(c *gin.Context) {
	ForbiddenWithConstant(c, errors.ErrForbidden)
}

// ResourceNotFound 资源不存在错误
func ResourceNotFound(c *gin.Context) {
	NotFoundWithConstant(c, errors.ErrNotFound)
}

// EmailExists 邮箱已存在错误
func EmailExists(c *gin.Context) {
	ErrorWithConstant(c, errors.ErrEmailExists, CodeBadRequest)
}

// TooManyRequests 请求过多错误
func TooManyRequests(c *gin.Context) {
	ErrorWithConstant(c, errors.ErrTooManyRequests, CodeTooManyRequests)
}

// ServerError 服务器错误
func ServerError(c *gin.Context) {
	ErrorWithConstant(c, errors.ErrInternalServer, CodeInternalError)
}

// SuccessWithPagination 分页成功响应便利函数
func SuccessWithPagination(c *gin.Context, data interface{}, total int64, page, limit int, message ...string) {
	totalPages := int(total / int64(limit))
	if total%int64(limit) > 0 {
		totalPages++
	}

	meta := PaginationMeta{
		Page:       page,
		PageSize:   limit,
		Total:      total,
		TotalPages: totalPages,
	}

	GetResponder(c).Pagination(data, meta, message...)
}

// ServiceUnavailable 服务不可用便利函数
func ServiceUnavailable(c *gin.Context, message ...string) {
	msg := "服务暂时不可用"
	if len(message) > 0 && message[0] != "" {
		msg = message[0]
	}
	GetResponder(c).Custom(CodeServiceError, msg, nil)
}

// BadRequest 400错误便利函数
func BadRequest(c *gin.Context, message ...string) {
	msg := "请求参数错误"
	if len(message) > 0 && message[0] != "" {
		msg = message[0]
	}
	GetResponder(c).BusinessError(msg, CodeBadRequest)
}

// Created 201创建成功便利函数
func Created(c *gin.Context, data interface{}, message ...string) {
	msg := "创建成功"
	if len(message) > 0 && message[0] != "" {
		msg = message[0]
	}

	c.JSON(http.StatusCreated, BaseResponse{
		Code:      ResponseCode(http.StatusCreated),
		Message:   msg,
		Data:      data,
		Success:   true,
		RequestID: getRequestID(c),
		Timestamp: time.Now().Unix(),
	})
}
